/**
 * @fileoverview
 * This script defines utilities for interacting with data from www.fly-ted.org.
 * @author <a href="http://purl.org/net/aliman">Alistair Miles</a>, Graham Klyne, Jun Zhao
 * @version $Revision:538 $ on $Date: 2008-08-27 09:08:41 +0100 (Wed, 27 Aug 2008) $ by $Author: aliman $
 * @requires YAHOO.util.Connect
 * @requires flyui.bdgp.GeneNameMappings
 * TODO license terms
 */

// create a namespace if not already defined
flyui.namespace("flyui.bdgp");

/**
 * TODO doc me
 */
flyui.bdgp.Service = function (endpointURL) {
	/**
	 * @private
	 */
	this._endpointURL = endpointURL;
}



/**
 * TODO doc me
 */
flyui.bdgp.Service.prototype.query = function (query, success, failure){
	flyui.info("flyui.bdgp.Service :: query request: "+query);
	
	// define the callback object
	var callback = {
		success: success,
		failure: failure
	};
			
	var url = this._buildURL(query);
	
	flyui.info("flyui.bdgp.Service :: make the request to "+url);
	var request = YAHOO.util.Connect.asyncRequest("GET", url, callback, null);
	
};


flyui.bdgp.Service.prototype.findImagesByAnyGeneLabel = function( geneLabel, success, failure) {
	flyui.info("flyui.bdgp.Service :: findImagesByAnyGeneLabel: "+geneLabel);
	
	var successAdapter = flyui.bdgp.Service._buildSuccessAdapterForFindImagesByAnyGeneLabel(success);

	var query = flyui.bdgp.Service._buildQueryForFindImagesByAnyGeneLabel(geneLabel);
	
	this.query(query, successAdapter, failure);	
}


/**
 * Construct the request URL for the given SPARQL query.
 * @private
 * @param {String} query a SPARQL query
 * @return a request URL
 * @type String
 */
flyui.bdgp.Service.prototype._buildURL = function( query ) {
	return this._endpointURL + "?output=json&query=" + escape(query);
};



/**
 * Return a success case request handler for the findImagesByAnyGeneLabel method.
 * @param {Function} adaptedSuccess the function to call with an array of Image objects
 * @return a success callback to use in the HTTP request
 * @type Function
 * @private
 * @static
 */
flyui.bdgp.Service._buildSuccessAdapterForFindImagesByAnyGeneLabel = function( adaptedSuccess ) {

	return function(responseObject) {
		
		flyui.debug("response received: "+responseObject.status);
		
		// try parsing response text as json
		flyui.debug("parsing response: "+responseObject.responseText);
		var resultSet = YAHOO.lang.JSON.parse(responseObject.responseText);
		
		// convert result set to an array of genes
		var images = flyui.bdgp.Stage.newInstancesFromSPARQLResults(resultSet);
		
		// complete the request
		adaptedSuccess(images);
	}

};



/**
 * Build a SPARQL query to retrieve images by bdgp gene name.
 * @param {String} anyName the gene name to search by
 * @return a SPARQL query
 * @type String
 * @private
 * @static
 */
flyui.bdgp.Service._buildQueryForFindImagesByAnyGeneLabel = function( geneLabel ) {

	var prefixes = 	"PREFIX bdgp: <http://purl.org/net/bdgp/schema/>  " +
					"PREFIX owl: <http://www.w3.org/2002/07/owl#> " +
					"PREFIX skos: <http://www.w3.org/2004/02/skos/core#> " +
					"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> " +
					"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> " +		
					"PREFIX : <http://www.wiwiss.fu-berlin.de/suhl/bizer/D2RQ/0.1#> " +
					"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
					"PREFIX dc: <http://purl.org/dc/elements/1.1/> ";					

//	var body = 		"SELECT DISTINCT ?thumbnailURL WHERE { " +
//						"?thumbnailURL digitalmedia:depicts [ oban:has_participants_from [ skos:altLabel '" + geneLabel + "' ] ] " +
//					"}";

//	var body = "select distinct ?imagepath where {" +
//				"?association bdgp:associate ?evidence; bdgp:geneProduct ?gp ." +
//				"?evidence bdgp:evidence ?img ." +
//				"?img rdf:type bdgp:Image ; bdgp:imagePath ?imagepath." +
//				"?gp skos:altLabel '" + geneLabel + "'; rdf:type bdgp:GeneProduct ." +
//				"}";

    var body = "select distinct ?imagepath ?stage ?developmentStage ?expression where {" +
              "?gp skos:altLabel '" + geneLabel + "'; rdf:type bdgp:GeneProduct ." +
              "?association bdgp:geneProduct ?gp ; bdgp:associate ?evidence ; bdgp:term ?term." +
              "?evidence bdgp:evidence ?img ." +
              "?img rdf:type bdgp:Image ; bdgp:imagePath ?imagepath." +
              "?img bdgp:imageToTerm ?stage." +
              "?stage bdgp:name ?developmentStage." +
              "?term bdgp:name ?expression ." +
              "}" + 
              "order by ?stage";
              
						
	var query = prefixes + body;

	return query;
};

flyui.bdgp.Stage = function (){
	var that = this;
	
	this.stageName = null;
	
	this.images = new Array();
	
	this.stageURI = null;
	
	this.addImage = function (image){
		flyui.util.appendIfNotMember(that.images, image);
	};
};

/**
 * TODO doc me
 */
flyui.bdgp.Stage.newInstancesFromSPARQLResults = function( resultSet ) {

	
	var stagePool = new flyui.bdgp.StagePool();
	var imagePool = new flyui.bdgp.ImagePool();
	var bindings = resultSet.results.bindings;
	
	for (var i=0; i<bindings.length; i++) {
		var binding = bindings[i];
		var stageURI = binding.stage.value;
		var stage = stagePool.get (stageURI);	
				
		if (binding.developmentStage && !stage.stageName) {
			stage.stageName = binding.developmentStage.value;
		}
		
		if (binding.imagepath){
			var imageURI = binding.imagepath.value;
			var image = imagePool.get(imageURI);
			
			if (!image.expressions){
				image.expressions = new Array();
			}

			if (binding.expression) {
				var expression = binding.expression.value;
				if (expression == "stage1-3" || expression == "stage4-6" || expression == "stage7-8" || expression == "stage9-10" || expression == "stage11-12" || expression == "stage13-16"){
					log ("test: " + expression + " is not an expression term" );
				}else{
					flyui.util.appendIfNotMember(image.expressions, expression);
				}
			}
			stage.addImage(image);
		}		
	}
	return stagePool.toArray();
};

/**
 * Create a pool of image objects.
 * @class
 * A pool of image objects.
 * @constructor
 */
 
flyui.bdgp.ImagePool = function() {
	/**
	 * @private
	 */
	this._pool = new Object();
};

flyui.bdgp.StagePool = function() {
	this._pool = new Array();
}

flyui.bdgp.StagePool.prototype.get = function( stageURI ) {
	
	var stage = this._pool[stageURI];
	
	if ( typeof stage == "undefined" || !stage ) {
		stage = new flyui.bdgp.Stage();
		stage.stageURI = stageURI;
		this._pool[stageURI] = stage;	
	}
	
	return stage;

};

flyui.bdgp.StagePool.prototype.toArray = function() {
	var array = new Array();	
	for (var key in this._pool) {
		array[array.length] = this._pool[key];
	}
	return array;
}

/**
 * Get a image object from the pool, or create a new one if it doesn't exist.
 * @param {String} imagepath 
 * @return a flyui.bdgp.Image object
 */
flyui.bdgp.ImagePool.prototype.get = function( imagepath ) {
	
	var image = this._pool[imagepath];
	
	if (!image ) {
		image = new Object();
		image.fullImageURL = "http://www.fruitfly.org/insituimages/insitu_images/" + imagepath;
		image.thumbnailURL = "http://www.fruitfly.org/insituimages/insitu_images/thumbnails/" + imagepath;
		this._pool[imagepath] = image;	
	}
	
	return image;

};

flyui.bdgp.ImagePool.prototype.toArray = function() {
	var array = new Array();
	for (var key in this._pool) {
		array[array.length] = this._pool[key];
	}
	return array;
}

